package com.freemalll.merchant.utils;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
import java.util.UUID;

public class HttpFormPostWithStreamUtil {

    private static final String BOUNDARY = "===" + UUID.randomUUID().toString() + "===";
    private static final String LINE_FEED = "\r\n";

    /**
     * 发送 POST 请求，格式为 multipart/form-data，支持 InputStream 类型的参数
     *
     * @param requestURL 请求地址
     * @param params     请求参数 (key -> value 或 key -> File 或 key -> InputStream)
     * @return 响应结果
     * @throws IOException
     */
    public static String sendPost(String requestURL, Map<String, Object> params) throws IOException {
        URL url = new URL(requestURL);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setDoInput(true);
        connection.setDoOutput(true);
        connection.setUseCaches(false);
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);

        try (
                OutputStream outputStream = connection.getOutputStream();
                PrintWriter writer = new PrintWriter(new OutputStreamWriter(outputStream))
        ) {
            if (params != null && !params.isEmpty()) {
                for (Map.Entry<String, Object> entry : params.entrySet()) {
                    String fieldname = entry.getKey();
                    Object value = entry.getValue();

                    if (value instanceof String) {
                        writeFormField(writer, fieldname, (String) value);
                    } else if (value instanceof File) {
                        writeFileFormField(writer, outputStream, fieldname, (File) value);
                    } else if (value instanceof InputStream) {
                        writeStreamFormField(writer, outputStream, fieldname, (InputStream) value, "image.jpg"); // 可传入文件名
                    }
                }
            }

            // 结束边界
            writer.append("--").append(BOUNDARY).append("--").append(LINE_FEED);
            writer.flush();
        }

        // 读取响应
        int responseCode = connection.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = in.readLine()) != null) {
                    response.append(line);
                }
                return response.toString();
            }
        } else {
            throw new IOException("Server responded with code: " + responseCode);
        }
    }

    /**
     * 写入文本字段
     */
    private static void writeFormField(PrintWriter writer, String name, String value) {
        writer.append("--").append(BOUNDARY).append(LINE_FEED);
        writer.append("Content-Disposition: form-data; name=\"").append(name).append("\"").append(LINE_FEED);
        writer.append(LINE_FEED);
        writer.append(value).append(LINE_FEED);
        writer.flush();
    }

    /**
     * 写入文件字段
     */
    private static void writeFileFormField(PrintWriter writer, OutputStream output, String fieldName, File file) throws IOException {
        writer.append("--").append(BOUNDARY).append(LINE_FEED);
        writer.append("Content-Disposition: form-data; name=\"").append(fieldName).append("\"; filename=\"").append(file.getName()).append("\"").append(LINE_FEED);
        writer.append("Content-Type: application/octet-stream").append(LINE_FEED);
        writer.append(LINE_FEED);
        writer.flush();

        try (FileInputStream inputStream = new FileInputStream(file)) {
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                output.write(buffer, 0, bytesRead);
            }
            output.flush();
        }
    }

    /**
     * 写入 InputStream 字段
     */
    private static void writeStreamFormField(PrintWriter writer, OutputStream output, String fieldName, InputStream inputStream, String fileName) throws IOException {
        writer.append("--").append(BOUNDARY).append(LINE_FEED);
        writer.append("Content-Disposition: form-data; name=\"").append(fieldName).append("\"; filename=\"").append(fileName).append("\"").append(LINE_FEED);
        writer.append("Content-Type: application/octet-stream").append(LINE_FEED);
        writer.append(LINE_FEED);
        writer.flush();

        byte[] buffer = new byte[4096];
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            output.write(buffer, 0, bytesRead);
        }
        output.flush();

        writer.append(LINE_FEED);
        writer.flush();

        // 关闭输入流
        inputStream.close();
    }
}
